package com.wh.wisdomsite.xbox.core.config.spring;


import com.wh.wisdomsite.xbox.core.security.impl.DefaultAppSecuretManager;
import com.wh.wisdomsite.xbox.core.security.impl.DefaultServiceAccessController;
import com.wh.wisdomsite.xbox.core.session.impl.DefaultSessionManager;
import com.wh.wisdomsite.xbox.core.security.impl.DefaultInvokeTimesController;
import com.wh.wisdomsite.xbox.core.threadpool.JobDispathcher;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;

/**
 *
 * @Package com.wh.wisdomsite.xbox.core.config.spring
 * @author 谢泽鹏
 * @date 2014年10月8日 下午4:02:14
 * @Copyright 个人版权所有
 * @Company 贵州万华科技有限公司Copyright (c) 2014
 * @version V1.0
 */
public class ServiceDispatcherBeanDefinitionParser implements BeanDefinitionParser {


    private static final Log logger = LogFactory.getLog(ServiceDispatcherBeanDefinitionParser.class);

    @Override
    public BeanDefinition parse(Element element, ParserContext parserContext) {

        Object source = parserContext.extractSource(element);
        CompositeComponentDefinition compDefinition = new CompositeComponentDefinition(element.getTagName(), source);
        parserContext.pushContainingComponent(compDefinition);

        RootBeanDefinition serviceDispatcherFactoryBean = new RootBeanDefinition(ServiceDispatherFactoryBean.class);

        String serviceDispatcherName = element.getAttribute("id");
        if (!StringUtils.hasText(serviceDispatcherName)) {
            serviceDispatcherName = parserContext.getReaderContext().generateBeanName(serviceDispatcherFactoryBean);
        }
        parserContext.getRegistry().registerBeanDefinition(serviceDispatcherName, serviceDispatcherFactoryBean);
        parserContext.registerComponent(new BeanComponentDefinition(serviceDispatcherFactoryBean, serviceDispatcherName));

        //设置sessionManger
        RuntimeBeanReference sessionManagerRef = getSessionManager(element, source, parserContext);
        serviceDispatcherFactoryBean.getPropertyValues().add("sessionManager", sessionManagerRef);

        //设置AppSecretManager
        RuntimeBeanReference appSecretManager = getAppSecretManager(element, source, parserContext);
        serviceDispatcherFactoryBean.getPropertyValues().add("appSecretManager", appSecretManager);
        //设置ServiceAccessController
        RuntimeBeanReference serviceAccessController = getServiceAccessController(element, source, parserContext);
        serviceDispatcherFactoryBean.getPropertyValues().add("serviceAccessController", serviceAccessController);
        //设置InvokeTimesController
        RuntimeBeanReference invokeTimesController = getInvokeTimesController(element, source, parserContext);
        serviceDispatcherFactoryBean.getPropertyValues().add("invokeTimesController", invokeTimesController);
        //设置JobDispathcher
        RuntimeBeanReference jobDispatcherRef = getJobDispatcher(element, source, parserContext);
        serviceDispatcherFactoryBean.getPropertyValues().add("jobDispathcher", jobDispatcherRef);

        //是否开启签名
        String signEnable = element.getAttribute("sign-enable");
        if (StringUtils.hasText(signEnable)) {
            serviceDispatcherFactoryBean.getPropertyValues().addPropertyValue("signEnable", Boolean.valueOf(signEnable));
        }

        //扩展错误信息
        String extErrorBasename = element.getAttribute("ext-error-base-name");
        if (StringUtils.hasText(extErrorBasename)) {
            serviceDispatcherFactoryBean.getPropertyValues().addPropertyValue("extErrorBaseName", extErrorBasename);
        }

        //扩展错误信息
        String eventAsync = element.getAttribute("event-async");
        if (StringUtils.hasText(eventAsync)) {
            serviceDispatcherFactoryBean.getPropertyValues().addPropertyValue("eventAsync", Boolean.valueOf(eventAsync));
        }

        parserContext.popAndRegisterContainingComponent();

        return null;
    }

    private RuntimeBeanReference getSessionManager(Element element, Object source, ParserContext parserContext) {
        RuntimeBeanReference sessionManagerRef = null;
        if (element.hasAttribute("session-manager")) {
            sessionManagerRef = new RuntimeBeanReference(element.getAttribute("session-manager"));
            logger.info("xbox 装配一个自定义的SessionManager:" + sessionManagerRef.getBeanName());

        } else {
            RootBeanDefinition sessionManagerDef = new RootBeanDefinition(DefaultSessionManager.class);
            sessionManagerDef.setSource(source);
            sessionManagerDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
            String sessionManagerName = parserContext.getReaderContext().registerWithGeneratedName(sessionManagerDef);
            parserContext.registerComponent(new BeanComponentDefinition(sessionManagerDef, sessionManagerName));
            sessionManagerRef = new RuntimeBeanReference(sessionManagerName);
            logger.info("xbox 装配一个默认的SessionManager:" + sessionManagerRef.getBeanName());
        }
            return sessionManagerRef;
    }

    private RuntimeBeanReference getAppSecretManager(Element element, Object source, ParserContext parserContext) {
        RuntimeBeanReference appSecretManagerRef;
        if (element.hasAttribute("app-secret-manager")) {
            appSecretManagerRef = new RuntimeBeanReference(element.getAttribute("app-secret-manager"));
            logger.info("xbox 装配一个自定义的密钥管理器:" + appSecretManagerRef.getBeanName());
        } else {
            RootBeanDefinition appSecretManagerDef = new RootBeanDefinition(DefaultAppSecuretManager.class);
            appSecretManagerDef.setSource(source);
            appSecretManagerDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
            String appSecretManagerName = parserContext.getReaderContext().registerWithGeneratedName(appSecretManagerDef);
            parserContext.registerComponent(new BeanComponentDefinition(appSecretManagerDef, appSecretManagerName));
            appSecretManagerRef = new RuntimeBeanReference(appSecretManagerName);
            logger.info("使用默认的密钥管理器:" + DefaultAppSecuretManager.class.getName());
        }
            return appSecretManagerRef;
    }

    private RuntimeBeanReference getInvokeTimesController(Element element, Object source, ParserContext parserContext) {
        RuntimeBeanReference invokeTimesControllerRef;
        if (element.hasAttribute("invoke-times-controller")) {
            invokeTimesControllerRef = new RuntimeBeanReference(element.getAttribute("invoke-times-controller"));
            logger.info("xbox 装配一个自定义的服务调用次数/频度控制器:" + invokeTimesControllerRef.getBeanName());
        } else {
            RootBeanDefinition invokeTimesControllerDef = new RootBeanDefinition(DefaultInvokeTimesController.class);
            invokeTimesControllerDef.setSource(source);
            invokeTimesControllerDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
            String invokeTimesControllerName = parserContext.getReaderContext().registerWithGeneratedName(invokeTimesControllerDef);
            parserContext.registerComponent(new BeanComponentDefinition(invokeTimesControllerDef, invokeTimesControllerName));
            invokeTimesControllerRef = new RuntimeBeanReference(invokeTimesControllerName);
            logger.info("使用默认的服务调用次数/频度控制器:" + DefaultInvokeTimesController.class.getName());
        }
        return invokeTimesControllerRef;
    }

    private RuntimeBeanReference getServiceAccessController(Element element, Object source, ParserContext parserContext) {
        RuntimeBeanReference serviceAccessControllerRef;
        if (element.hasAttribute("service-access-controller")) {
            serviceAccessControllerRef = new RuntimeBeanReference(element.getAttribute("service-access-controller"));
            logger.info("xbox 装配一个自定义的服务访问控制器:" + serviceAccessControllerRef.getBeanName());
        } else {
            RootBeanDefinition serviceAccessControllerDef = new RootBeanDefinition(DefaultServiceAccessController.class);
            serviceAccessControllerDef.setSource(source);
            serviceAccessControllerDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
            String serviceAccessControllerName = parserContext.getReaderContext().registerWithGeneratedName(serviceAccessControllerDef);
            parserContext.registerComponent(new BeanComponentDefinition(serviceAccessControllerDef, serviceAccessControllerName));
            serviceAccessControllerRef = new RuntimeBeanReference(serviceAccessControllerName);
            logger.info("使用默认的服务访问控制器:" + DefaultServiceAccessController.class.getName());
        }
            return serviceAccessControllerRef;
    }


    private RuntimeBeanReference getJobDispatcher(Element element, Object source, ParserContext parserContext) {
        RuntimeBeanReference jobDispatcherRef = null;

        if (element.hasAttribute("job-dispathcher")) {
            jobDispatcherRef = new RuntimeBeanReference(element.getAttribute("job-dispathcher"));
            logger.info("xbox 装配JobDispathcer:" + jobDispatcherRef.getBeanName());
        } else {
            RootBeanDefinition jobDispatherDef = new RootBeanDefinition(JobDispathcher.class);
            jobDispatherDef.setSource(source);
            jobDispatherDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
            String jobDispatcherName = parserContext.getReaderContext().registerWithGeneratedName(jobDispatherDef);
            parserContext.registerComponent(new BeanComponentDefinition(jobDispatherDef, jobDispatcherName));
            jobDispatcherRef = new RuntimeBeanReference(jobDispatcherName);
            logger.info("xbox 装配了一个默认的JobDispathcer,没有设置线程权重,请设置!" + JobDispathcher.class.getName());
        }
            return jobDispatcherRef;
    }


}
